package com.wangdong.network.ui;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.JsonReader;
import android.util.JsonWriter;
import android.widget.TextView;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.wangdong.network.R;
import com.wangdong.network.User;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.util.List;

public class GsonActivity extends AppCompatActivity {
    private TextView text;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main3);
        text = (TextView) findViewById(R.id.tv_text1);

        Gson gson = new Gson();
/**基本类型使用*/
//        int i = gson.fromJson("100", int.class);              //100
//        double d = gson.fromJson("\"99.99\"", double.class);  //99.99
//        boolean b = gson.fromJson("true", boolean.class);     // true
//        String str = gson.fromJson("String", String.class);   // String
//
//        String jsonNumber = gson.toJson(100);       // 100
//        String jsonBoolean = gson.toJson(false);    // false
//        String jsonString = gson.toJson("String"); //"String"
/**简单对象使用*/
//        User user = new User("怪盗kidou",24);
//        String jsonObject = gson.toJson(user); // {"name":"怪盗kidou","age":24}
//        text.setText(jsonObject);

//          String jsonString = "{\"name\":\"怪盗kidou\",\"age\":24}";
//          User user = gson.fromJson(jsonString, User.class);
//          text.setText(user.getName());

        /*POJO 和JavaBean是我们常见的两个关键字，一般容易混淆，POJO全称是Plain Ordinary Java Object / Pure Old Java Object，
        中文可以翻译成：普通Java类，具有一部分getter/setter方法的那种类就可以称作POJO，但是JavaBean则比 POJO复杂很多，*/



/**解决 POJO类中 属性名字符的 多样性 例如
 * {"name":"怪盗kidou","age":24,"emailAddress":"ikidou@example.com"}
 * {"name":"怪盗kidou","age":24,"email_address":"ikidou@example.com"}
 * emailaddress这个字符 PHP和Java 命名规则不一样，但要兼容
 * 这个时候用到SerializedName的注解类*/

//        @SerializedName("email_address")
//        public String emailAddress;

        /**{"name":"怪盗kidou","age":24,"emailAddress":"ikidou@example.com"}
         {"name":"怪盗kidou","age":24,"email_address":"ikidou@example.com"}
         {"name":"怪盗kidou","age":24,"email":"ikidou@example.com"}
         如果出现这中情况：
         SerializedName注解提供了两个属性，上面用到了其中一个，别外还有一个属性alternate，接收一个String数组。
         注：alternate需要2.4版本

*/
//        @SerializedName(value = "emailAddress", alternate = {"email", "email_address"})
//        public String emailAddress;//我现在gson版本是2.2.4所以没有alternate注解会报红。

        String json = "{\"name\":\"怪盗kidou\",\"age\":24," +
                "\"emailAddress\":\"ikidou_1@example.om\"," +
                "\"email\":\"ikidou_2@example.cm\"," +
                "\"email_address\":\"ikidou_3@example.co\"}";
//        User user2 = gson.fromJson(json, User.class);
//        text.setText(user2.getEmailAddress()); // ikidou_3@example.co  注：当多种情况同时出时，以最后一个出现的值为准。

/**数组使用*/
        String jsonArray = "[\"Android\",\"Java\",\"PHP\"]";
//        String[] strings = gson.fromJson(jsonArray, String[].class);

        /**但对于List将上面的代码中的 String[].class 直接改为 List<String>.class 是行不通的。
         * 对于Java来说List<String> 和List<User> 这俩个的字节码文件只一个那就是List.class，
         * 这是Java泛型使用时要注意的问题 泛型擦除。*/
//        为了解决的上面的问题，Gson为我们提供了TypeToken来实现对泛型的支持，所以当我们希望使用将以上的数据解析为List<String>时需要这样写。
        List<String> stringList = gson.fromJson(jsonArray, new TypeToken<List<String>>() {}.getType());
//        注：TypeToken的构造方法是protected修饰的,所以上面才会写成new TypeToken<List<String>>() {}.getType()
//            而不是  new TypeToken<List<String>>().getType()

//        text.setText(stringList.get(1));

/**泛型解析对接口POJO的设计影响*/

/*  {"code":"0","message":"success","data":{}} data对象型

    {"code":"0","message":"success","data":[]} data数组型

public class Result<T> {
    public int code;
    public String message;
    public T data;
}

那么对于data字段是User时则可以写为 Result<User> ,当是个列表的时候为 Result<List<User>>，其它同理。
*/


    }

    /**
     * 流式反序列化
     */
    public void mGson() throws IOException {
        String json = "{\"name\":\"怪盗kidou\",\"age\":\"24\"}";
        User user = new User();
        JsonReader reader = new JsonReader(new StringReader(json));
        try {
            reader.beginObject(); // throws IOException
        } catch (IOException e) {
            e.printStackTrace();
        }
        while (reader.hasNext()) {
            String s = reader.nextName();
            switch (s) {
                case "name":
                    user.name = reader.nextString();
                    break;
                case "age":
                    user.age = reader.nextInt(); //自动转换
                    break;
                case "email":
                    user.emailAddress = reader.nextString();
                    break;
            }
        }
        reader.endObject(); // throws IOException

        System.out.println(user.name);  // 怪盗kidou
        System.out.println(user.age);   // 24
        System.out.println(user.emailAddress); // ikidou@example.com



    }

    /**
     * 创建Gson 特定对象
     */
    public void onGson(){
        Gson gson = new GsonBuilder()
                //序列化null
                .serializeNulls()
                // 设置日期时间格式，另有2个重载方法
                // 在序列化和反序化时均生效
                .setDateFormat("yyyy-MM-dd")
                // 禁此序列化内部类
                .disableInnerClassSerialization()
                //生成不可执行的Json（多了 )]}' 这4个字符）
                .generateNonExecutableJson()
                //禁止转义html标签
                .disableHtmlEscaping()
                //格式化输出
                .setPrettyPrinting()
                .create();


    }

    /**
     * 反序列化
     * @throws IOException
     */
    public void smGson() throws IOException {
        JsonWriter writer = new JsonWriter(new OutputStreamWriter(System.out));
        writer.beginObject() // throws IOException
                .name("name").value("怪盗kidou")
                .name("age").value(24)
                .name("email").nullValue() //演示null
                .endObject(); // throws IOException
        writer.flush(); // throws IOException
//{"name":"怪盗kidou","age":24,"email":null}


    }

    /**
     * 过滤不需要的字段，然后序列化
     */
    public void guoluZiDu(){



    }
}
